﻿using System.Linq;
using AutoMapper;
using microsoft_TODO.DTOs;
using microsoft_TODO.Models;
using microsoft_TODO.MongoCore;
using MongoDB.Bson;
using MongoDB.Driver;
using server.DTOs;

namespace microsoft_TODO.ServiceCore.Services
{
    public class TaskService : ITaskService
    {
        IListRepository _listRepository;
        IMapper _mapper;

        public TaskService(
          IMapper mapper,
          IListRepository listRepository)
        {
            _mapper = mapper;
            _listRepository = listRepository;
        }

        public void TurnTodayTasksToFalse(string uid)
        {
            var checklists = _listRepository.GetAll();
            foreach (var checklist in checklists)
            {
                foreach (var task in checklist.Tasks)
                {
                    if (task.Today)
                    {
                        _listRepository.UpdateTaskViaIndexOfArray(
                          checklist.Id,
                          checklist.Tasks.IndexOf(task),
                          "today",
                          BsonBoolean.Create(false)
                        );
                    }
                }
            }
        }

        public Task AddNewTask(NewTaskDto dto)
        {
            var task = new Task { Todo = dto.Todo };
            _listRepository.Update(
              u => u.Id == dto.ListId,
              Builders<CheckList<Task>>.Update.Push(u => u.Tasks, task)
            );
            var newTask = _listRepository.GetAll().FirstOrDefault(u => u.Id == dto.ListId).Tasks.FirstOrDefault(u => u.Todo == dto.Todo);
            return newTask;
        }

        public Task AddTodayTask(NewTaskDto dto)
        {
            var task = new Task { Todo = dto.Todo, Today = true };
            _listRepository.Update(
              u => u.Id == dto.ListId,
              Builders<CheckList<Task>>.Update.Push(u => u.Tasks, task)
            );
            var newTask = _listRepository.GetAll().FirstOrDefault(u => u.Id == dto.ListId).Tasks.FirstOrDefault(u => u.Todo == dto.Todo);
            return newTask;
        }

        public void MoveToAnotherList(MoveTaskDto dto)
        {
            var task = _listRepository.FirstOrDefault(u => u.Id == dto.fromListId)
              .Tasks.ElementAt(dto.Index);
            RemoveTask(dto.fromListId, dto.Index);
            _listRepository.Update(
              u => u.Id == dto.toListId,
              Builders<CheckList<Task>>.Update.Push(u => u.Tasks, task)
            );
        }

        public bool RemoveTask(string lid, int index)
        {
            return _listRepository.RemoveTaskViaIndexOfArray(lid, index);
        }

        public bool ClearTaskDeadline(string lid, int index)
        {
            return _listRepository.UpdateTaskViaIndexOfArray(lid, index, "deadline", BsonNull.Value);
        }

        public bool UpdateTask(PutTaskDto dto)
        {
            var listId = dto.ListId;
            var index = dto.Index;
            string field = string.Empty;
            BsonValue value = BsonNull.Value;

            if (!string.IsNullOrWhiteSpace(dto.Todo))
            {
                field = "todo";
                value = BsonString.Create(dto.Todo);
            }
            if (dto.IsDone.HasValue)
            {
                field = "isDone";
                value = BsonBoolean.Create(dto.IsDone.Value);
            }
            if (dto.Today.HasValue)
            {
                field = "today";
                value = BsonBoolean.Create(dto.Today.Value);
            }
            if (dto.ReminderTime.HasValue)
            {
                field = "reminderTime";
                value = BsonDateTime.Create(dto.ReminderTime.Value);
            }
            if (dto.Deadline.HasValue)
            {
                field = "deadline";
                value = BsonDateTime.Create(dto.Deadline.Value);
            }
            if (!string.IsNullOrEmpty(dto.Notes))
            {
                field = "notes";
                value = BsonString.Create(dto.Notes);
            }

            return _listRepository.UpdateTaskViaIndexOfArray(
              listId,
              index,
              field,
              value
            );
        }
    }
}
